/*
 * @lc app=leetcode.cn id=71 lang=cpp
 *
 * [71] 简化路径
 */

// @lc code=start
#include <bits/stdc++.h>
using namespace std;
class Solution
{
public:
    enum STATE
    {
        s0,
        s1,
        s2,
        s3,
        s4,
        s5,
        s6,
        s7
    };
    /**
     * @brief 需要保证传入的路径不是以'/'结尾的，而是以 ".." 结尾的
     *
     * @param ans
     */
    void returnParentDir(char *ans)
    {
        int len = strlen(ans);
        if (len == 3) //说明是 "/.."，不能返回根目录的上一级
        {
            ans[1] = 0;
            return;
        }
        len -= 4;
        while (ans[len] != '/')
            len--;
        ans[len + 1] = 0;
        return;
    }
    string simplifyPath(string path)
    {
        STATE state = s1;
        char ans[4096] = {0};
        int id_ans = 0;
        ans[id_ans++] = '/';
        for (int i = 0;state != s7; i++)
        {
            char ch = 0;
            if (i < path.size())
                ch = path[i]; //事实上不会越界，因为 最后一位肯定是 '\0'
            ans[id_ans++] = ch;
            switch (state)
            {
            case s1:
            {
                if (ch == 0)
                    state = s7;
                else if (ch == '/')
                {
                    state = s1;
                    id_ans--;
                }
                else if (ch == '.')
                {
                    state = s2;
                }
                else
                {
                    state = s4;
                }
            }
            break;

            case s2:
            {
                if (ch == 0)
                    state = s5;
                else if (ch == '.')
                {
                    state = s3;
                }
                else if (ch == '/')
                {
                    state = s5;
                }
                else
                {
                    state = s4;
                }
            }
            break;

            case s3:
            {
                if (ch == 0)
                    state = s6;
                else if (ch == '.')
                {
                    state = s4;
                }
                else if (ch == '/')
                {
                    state = s6;
                }
                else
                {
                    state = s4;
                }
            }
            break;

            case s4:
            {
                if (ch == 0)
                    state = s7;
                else if (ch == '.')
                {
                    state = s4;
                }
                else if (ch == '/')
                {
                    state = s1;
                }
                else
                {
                    state = s4;
                }
            }
            break;

            case s5:
            {
                state = s1;
                i--;
                id_ans -= 3;
                ans[id_ans] = 0;
                if (ch == 0)
                    state = s7;
            }
            break;

            case s6:
            {
                state = s1;
                i--;
                id_ans -= 2;
                ans[id_ans] = 0;
                returnParentDir(ans);
                id_ans = strlen(ans);
                if (ch == 0)
                    state = s7;
            }
            break;

            default:
                state = s7;
                break;
            }
        }

        ans[id_ans] = 0;
        while (ans[id_ans] == 0)
            id_ans--;
        while (id_ans > 0 && ans[id_ans] == '/')
        {
            ans[id_ans--] = 0;
        }
        return ans;
    }
};

// int main()
// {
//     cout << Solution().simplifyPath("/.") << endl;
//     return 0;
// }

// @lc code=end
